import math
import numpy as np


def calculate_angles_between_lines(a, b, c, d):
    """
    计算线段AB所在直线与线段CD所在直线的夹角（弧度值）
    参数:
    a, b: 线段AB的端点坐标 (x, y)
    c, d: 线段CD的端点坐标 (x, y)
    返回:
    angle_rad: 两条直线之间的夹角弧度值（范围：0 到 π/2）
    """
    # 计算向量AB和向量CD
    vector_ab = (b[0] - a[0], b[1] - a[1])
    vector_cd = (d[0] - c[0], d[1] - c[1])

    # 计算向量的点积
    dot_product = vector_ab[0] * vector_cd[0] + vector_ab[1] * vector_cd[1]

    # 计算向量的模长
    norm_ab = math.sqrt(vector_ab[0] ** 2 + vector_ab[1] ** 2)
    norm_cd = math.sqrt(vector_cd[0] ** 2 + vector_cd[1] ** 2)

    # 避免除零错误
    if norm_ab * norm_cd == 0:
        return 0.0

    # 计算夹角的余弦值
    cos_angle = dot_product / (norm_ab * norm_cd)

    # 处理浮点数精度问题，确保cos_angle在[-1, 1]范围内
    cos_angle = max(-1.0, min(1.0, cos_angle))

    # 计算夹角弧度值
    angle_rad = math.acos(cos_angle)

    # 返回较小的夹角（0到π/2之间）
    return min(angle_rad, math.pi - angle_rad)


# 使用numpy的版本（更简洁）
def calculate_line_angle_np(a, b, c, d):
    """
    使用numpy计算线段AB所在直线与线段CD所在直线的夹角（弧度值）
    """
    # 转换为numpy数组
    a = np.array(a)
    b = np.array(b)
    c = np.array(c)
    d = np.array(d)

    # 计算方向向量
    vector_ab = b - a
    vector_cd = d - c

    # 计算向量夹角
    dot_product = np.dot(vector_ab, vector_cd)
    norm_ab = np.linalg.norm(vector_ab)
    norm_cd = np.linalg.norm(vector_cd)

    if norm_ab * norm_cd == 0:
        return 0.0

    cos_angle = dot_product / (norm_ab * norm_cd)
    cos_angle = np.clip(cos_angle, -1.0, 1.0)

    angle_rad = np.arccos(cos_angle)

    # 返回较小的夹角
    return min(angle_rad, np.pi - angle_rad)


# 示例用法
if __name__ == "__main__":
    # 示例1：两条垂直的直线
    a, b = (0, 0), (1, 0)  # 水平线
    c, d = (0, 0), (0, 1)  # 垂直线
    angle = calculate_line_angle(a, b, c, d)
    print(f"水平线与垂直线的夹角: {angle:.4f} 弧度 ({math.degrees(angle):.2f} 度)")
    # 应该输出约 1.5708 弧度 (90度)

    # 示例2：两条平行的直线
    a, b = (0, 0), (1, 0)  # 水平线
    c, d = (0, 1), (1, 1)  # 水平线
    angle = calculate_line_angle(a, b, c, d)
    print(f"两条水平线的夹角: {angle:.4f} 弧度 ({math.degrees(angle):.2f} 度)")
    # 应该输出约 0 弧度 (0度)

    # 示例3：45度角的直线
    a, b = (0, 0), (1, 1)  # 45度线
    c, d = (0, 0), (1, 0)  # 水平线
    angle = calculate_line_angle(a, b, c, d)
    print(f"45度线与水平线的夹角: {angle:.4f} 弧度 ({math.degrees(angle):.2f} 度)")
    # 应该输出约 0.7854 弧度 (45度)